package com.yfbao.horizon.schedule.tk.sch;

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tags;
import io.micrometer.core.instrument.Timer;
import io.micrometer.prometheus.PrometheusMeterRegistry;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class DynamicMetrics {

    private static Map<String,Counter> counterMap =new HashMap<>();
    private static Map<String, Timer> timerMap =new HashMap<>();

    private final MeterRegistry meterRegistry;
    private ApplicationContext CONTEXT;

    public DynamicMetrics(MeterRegistry meterRegistry, ConfigurableApplicationContext applicationContext) {
        this.meterRegistry = meterRegistry;
        this.CONTEXT = applicationContext;
    }

    private Timer registerTimer(String status, String taskName){
        String metricName = "schedule.ctp.fail";
        if(status.equals("success")){
            metricName = "schedule.ctp.success";
        }
        log.info("Metric timer registered: " + metricName+","+taskName);

        MeterRegistry bean = CONTEXT.getBean(PrometheusMeterRegistry.class);
        if( bean !=null){
            log.info("bean name:"+bean.getClass().getName());
        }else {
            log.info("bean is null");
        }
        return Timer.builder(metricName)
                .tag("status",status)
                .tag("type","ctpSchedule")
                .tag("task",taskName)
                .register(meterRegistry);
    }

    private Timer getMetric(String status, String taskName){
        String key=taskName+"_"+status;
        Timer timer = timerMap.get(key);
        if(timer ==null){
            Timer success = registerTimer(status,taskName );
            timerMap.put(key,success);
            timer = success;
        }
        return timer;
    }

    public void sucessCostTime(String name, long cost){
        try {
            Timer timer = getMetric("success",name);
            timer.record(cost, TimeUnit.MILLISECONDS);
        } catch (Exception e) {}
    }

    public void failCostTime(String name, long cost){
        try {
            Timer timer = getMetric("fail",name);
            timer.record(cost, TimeUnit.MILLISECONDS);
        } catch (Exception e) {}
    }
}
